/**
 * 日期格式化工具
 * 提供各种日期格式转换功能
 */

/**
 * 格式化日期
 * @param {Date|string|number} date - 日期对象、ISO字符串或时间戳
 * @param {string} format - 格式化字符串，默认为'YYYY-MM-DD HH:mm:ss'
 * @returns {string} - 格式化后的日期字符串
 */
export function formatTime(date, format = 'YYYY-MM-DD HH:mm:ss') {
  if (!date) return '';
  
  // 处理日期对象
  let d;
  if (typeof date === 'string') {
    // 处理ISO格式字符串
    if (date.includes('T') && date.includes('Z')) {
      d = new Date(date.replace('T', ' ').replace('Z', ''));
    } else {
      d = new Date(date);
    }
  } else if (typeof date === 'number') {
    // 处理时间戳
    d = new Date(date);
  } else if (date instanceof Date) {
    d = date;
  } else {
    return '';
  }
  
  // 检查日期是否有效
  if (isNaN(d.getTime())) return '';
  
  const o = {
    'M+': d.getMonth() + 1, // 月份
    'D+': d.getDate(), // 日
    'H+': d.getHours(), // 小时
    'm+': d.getMinutes(), // 分
    's+': d.getSeconds(), // 秒
    'q+': Math.floor((d.getMonth() + 3) / 3), // 季度
    'S': d.getMilliseconds() // 毫秒
  };
  
  // 处理年份
  if (/(Y+)/.test(format)) {
    format = format.replace(RegExp.$1, (d.getFullYear() + '').substr(4 - RegExp.$1.length));
  }
  
  // 处理其他格式
  for (const k in o) {
    if (new RegExp('(' + k + ')').test(format)) {
      format = format.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
    }
  }
  
  return format;
}

/**
 * 格式化日期为中文
 * @param {Date|string|number} date - 日期对象、字符串或时间戳
 * @param {boolean} showTime - 是否显示时间
 * @returns {string} - 格式化后的中文日期字符串
 */
export function formatTimeChinese(date, showTime = false) {
  if (!date) return '';
  
  const d = new Date(date);
  
  // 检查日期是否有效
  if (isNaN(d.getTime())) return '';
  
  const year = d.getFullYear();
  const month = d.getMonth() + 1;
  const day = d.getDate();
  
  let result = `${year}年${month}月${day}日`;
  
  if (showTime) {
    const hours = d.getHours().toString().padStart(2, '0');
    const minutes = d.getMinutes().toString().padStart(2, '0');
    const seconds = d.getSeconds().toString().padStart(2, '0');
    
    result += ` ${hours}:${minutes}:${seconds}`;
  }
  
  return result;
}

/**
 * 计算两个日期之间的天数差
 * @param {Date|string|number} startDate - 开始日期
 * @param {Date|string|number} endDate - 结束日期
 * @returns {number} - 天数差
 */
export function daysBetween(startDate, endDate) {
  if (!startDate || !endDate) return 0;
  
  const start = new Date(startDate);
  const end = new Date(endDate);
  
  // 检查日期是否有效
  if (isNaN(start.getTime()) || isNaN(end.getTime())) return 0;
  
  // 计算毫秒差
  const diffTime = Math.abs(end - start);
  
  // 转换为天数
  const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
  
  return diffDays;
}

/**
 * 获取相对时间
 * @param {Date|string|number} date - 日期对象、字符串或时间戳
 * @returns {string} - 相对时间字符串
 */
export function getRelativeTime(date) {
  if (!date) return '';
  
  const d = new Date(date);
  
  // 检查日期是否有效
  if (isNaN(d.getTime())) return '';
  
  const now = new Date();
  const diff = now - d;
  
  // 计算各时间单位
  const seconds = Math.floor(diff / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);
  const months = Math.floor(days / 30);
  const years = Math.floor(months / 12);
  
  // 根据时间差返回相对时间
  if (years > 0) {
    return `${years}年前`;
  } else if (months > 0) {
    return `${months}个月前`;
  } else if (days > 0) {
    return `${days}天前`;
  } else if (hours > 0) {
    return `${hours}小时前`;
  } else if (minutes > 0) {
    return `${minutes}分钟前`;
  } else {
    return '刚刚';
  }
}

/**
 * 获取指定日期所在周的周一
 * @param {Date|string|number} date - 日期对象、字符串或时间戳
 * @returns {Date} - 周一的日期对象
 */
export function getMondayOfWeek(date) {
  if (!date) return new Date();
  
  const d = new Date(date);
  
  // 检查日期是否有效
  if (isNaN(d.getTime())) return new Date();
  
  const day = d.getDay();
  const diff = d.getDate() - day + (day === 0 ? -6 : 1); // 调整为周一
  
  const monday = new Date(d);
  monday.setDate(diff);
  monday.setHours(0, 0, 0, 0);
  
  return monday;
}

/**
 * 获取指定日期所在月的第一天
 * @param {Date|string|number} date - 日期对象、字符串或时间戳
 * @returns {Date} - 当月第一天的日期对象
 */
export function getFirstDayOfMonth(date) {
  if (!date) return new Date();
  
  const d = new Date(date);
  
  // 检查日期是否有效
  if (isNaN(d.getTime())) return new Date();
  
  const firstDay = new Date(d.getFullYear(), d.getMonth(), 1);
  firstDay.setHours(0, 0, 0, 0);
  
  return firstDay;
}

/**
 * 获取指定日期所在月的最后一天
 * @param {Date|string|number} date - 日期对象、字符串或时间戳
 * @returns {Date} - 当月最后一天的日期对象
 */
export function getLastDayOfMonth(date) {
  if (!date) return new Date();
  
  const d = new Date(date);
  
  // 检查日期是否有效
  if (isNaN(d.getTime())) return new Date();
  
  const lastDay = new Date(d.getFullYear(), d.getMonth() + 1, 0);
  lastDay.setHours(0, 0, 0, 0);
  
  return lastDay;
}

/**
 * 检查日期是否为今天
 * @param {Date|string|number} date - 日期对象、字符串或时间戳
 * @returns {boolean} - 是否为今天
 */
export function isToday(date) {
  if (!date) return false;
  
  const d = new Date(date);
  const today = new Date();
  
  // 检查日期是否有效
  if (isNaN(d.getTime())) return false;
  
  return d.getDate() === today.getDate() &&
         d.getMonth() === today.getMonth() &&
         d.getFullYear() === today.getFullYear();
}

/**
 * 检查日期是否为昨天
 * @param {Date|string|number} date - 日期对象、字符串或时间戳
 * @returns {boolean} - 是否为昨天
 */
export function isYesterday(date) {
  if (!date) return false;
  
  const d = new Date(date);
  const yesterday = new Date();
  yesterday.setDate(yesterday.getDate() - 1);
  
  // 检查日期是否有效
  if (isNaN(d.getTime())) return false;
  
  return d.getDate() === yesterday.getDate() &&
         d.getMonth() === yesterday.getMonth() &&
         d.getFullYear() === yesterday.getFullYear();
}

/**
 * 检查日期是否为明天
 * @param {Date|string|number} date - 日期对象、字符串或时间戳
 * @returns {boolean} - 是否为明天
 */
export function isTomorrow(date) {
  if (!date) return false;
  
  const d = new Date(date);
  const tomorrow = new Date();
  tomorrow.setDate(tomorrow.getDate() + 1);
  
  // 检查日期是否有效
  if (isNaN(d.getTime())) return false;
  
  return d.getDate() === tomorrow.getDate() &&
         d.getMonth() === tomorrow.getMonth() &&
         d.getFullYear() === tomorrow.getFullYear();
}
